<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>2022-8-25晚作业</title>
</head>

<body>
    <script>
        console.log(1);//同步任务 直接输出1
        Promise.resolve().then(() => {
            console.log(3);//这里的then是微任务 放入微任务队列3
            setTimeout(() => {//定时器是宏任务 放入宏任务队列5
                console.log(5);
            }, 0);
        });
        setTimeout(() => {//定时器 放入宏任务队列 2
            console.log(2);
        }, 0);
        console.log(4);//同步任务 直接输出 4
        /* 
          分析:首先我们先排一下顺序
          同步:1  4  
          微任务:3
          宏任务:2  5  
          同步任务先执行 所以这里的顺序是1  4  3  2  5
          */
        //===========================T1↓============================
        //T1
        function fn1() {
            console.log(1);//调用了fn1函数 这里首先执行 顺序1
            fn2();//调用了fn2函数 
        }
        function fn2() {//执行到这 但是它里面有一个定时器 
            setTimeout(() => {//定时器是宏任务 这里要把定时器放入宏任务队列
                console.log(2);
            }, 100);
            console.log(3);// 同步任务 顺序2
            //new Promise 同步↓   
            new Promise(function (res, rej) {
                console.log(4);//这里的4同步任务 直接执行 顺序3
                //这里的res是把promise状态转成 成功 用的
                res(5);
            }).then((res) => {//then 和 resolve 异步 微任务 加入到微任务队列中
                console.log(res); //5
            });
        }
        fn1();
        /*
        分析:按照执行顺序分类
        同步任务：1 3 4
        微任务：5
        宏任务：2
        代码从上往下执行 函数不调用不执行 有同步任务直接执行
        首先这里调用fn1()函数 fn1函数里面是输出语句 同步 直接输出 
        后又调用fn2 fn2里面有一个定时器 定时器是一个宏任务 加入到宏任务队列当中
        再往下执行 log(3)并没有包括在计时器里面 所以这里是同步任务 可以直接执行
        new Promise是同步任务 可以直接输出4  再往下执行
        .then是微任务 es6定的  所以它加入到微任务队列 
        最后 整合一下顺序 先同步>异步微>异步宏 1 3 4 5 2
        */
        //===========================T2↓========================================
        setTimeout(() => {//定时器宏任务 进入到宏任务队列 顺序1
            console.log(1);
            setTimeout(() => {//当1和4执行完毕之后 定时器2 3在进入到宏任务队列当中
                console.log(2);//顺序3
            }, 0);
            setTimeout(() => {//顺序4
                console.log(3);
            }, 0);
        }, 0);
        setTimeout(() => {//和定时器1是同级 1进去了4紧接着进去 顺序2
            console.log(4);
        }, 0);
        /*
        分析:
        同步:
        微任务:
        宏任务:1 4 2 3
        这里都是定时器 都是宏任务 那么会不会是1 2 3 4呢?
        当然不是 因为我们可以发现2 3的定时器都在定时器1里面 
        首先 定时器1和定时器4进入到宏任务队列当中 
        这里要注意的是定时器1要比定时器4先进  
        定时器1先进先出 所以这里首先执行定时器1 其次是4
        那么 1和4都执行完毕了 现在就剩下2和3了  
        2和3再把它们丢进宏任务队列当中 
        所以 这里的执行顺序是1 4 2 3
        */
        //========================T3↓====================================
        console.log("script start");//顺序 1

        setTimeout(() => {
            console.log("timeout1");//顺序 5
        }, 10);

        new Promise((resolve) => {//顺序 2
            console.log("promise1");
            resolve();
            setTimeout(() => {//顺序 6
                console.log("timeout2");
            }, 10);
        }).then(() => {
            console.log("then1");//顺序 4
        });
        console.log("script end");//顺序 3
        /*
        分析:
        同步:("script start")  ('promise1') ('script end')
        微任务:('then1')
        宏任务:('timeout1') ("timeout2");
        首先执行script start 它在最上面和最外层不受谁的影响
        往下执行 碰到定时器('timeout1')进入到宏任务队列当中
        当执行到这的时候new Promise是同步任务 直接输出('promise1')
        再往下走 碰到('timeout2')定时器 进入宏任务队列
        .then是微任务 加入微任务队列  最后是同步任务('script end')
        顺序是("script start")  ('promise1') ('script end')
        ('then1') ('timeout1') ("timeout2");
        */
        //===========================T4===================================
        async function async1() {
            console.log("A");//同步直接输出 顺序2
            async2();//再调用async2函数 
            console.log("B");//async2调用完毕 执行这里的代码同步 顺序4
            // async1执行完毕之后 回到调用它的地方
        }
        async function async2() {
            console.log("C");//这里是同步 直接输出 顺序3
            // 然后async2执行完回到调用它的地方
        }
        //顺序1 ↓
        console.log("D");//代码先会执行这一条 因为('D')不受谁的影响 也没包含在谁的里面
        setTimeout(() => {//碰到定时器 直接进入宏任务队列中 F是第一个进入宏任务队列中的
            console.log("F");
        }, 0);
        async1();//调用async1函数  调用完async1代码继续往下走
        new Promise((resolve) => {//同步任务 直接执行('G') 顺序 5 
            console.log("G");
            resolve();
        }).then(() => {//微任务 进入微任务队列
            console.log("H");
        });
        console.log("I");//顺序6
        /*
        分析:
        同步:D A C B G I
        微任务:H 
        宏任务:F 
        代码首先执行D 然后碰到了定时器 加入宏任务队列  然后调用了async1函数 
        输出A 同步任务 接着又调用async2 找到async2 输出C 同步任务
        async2函数执行完了就会回到调用它的地方继续往下执行 输出B 同步任务
        然后回到async1 接着往下执行 new Promise 同步任务 输出G 
        碰到了.then 它是微任务 进入微任务队列 然后又碰到了同步任务I
        执行顺序就是 D A C B G I H F
       */
        //===============================T5==================================
        async function haha() {
            console.log(1);//同步任务 
            //微任务
            await xixi(); //等await xixi()代码执行完 才能执行下面的代码
            console.log(2);//await 是微任务 等待
            console.log(4);
            heihei();//因为heihei函数在await后面所以也进入了微任务队列
        }
        async function xixi() {
            console.log(3);
            //宏任务
            setTimeout(() => {
                console.log(6);//加入到宏任务队列中 
            }, 0);
        }
        function heihei() {
            console.log(5);
        }
        haha();
        /*
        分析:
        同步:1 3
        微任务:2 4 5
        宏任务:6 
       执行顺序就是 1 3 2 4 5 6
        */
        //=============================T6=================================
        async function async1() {
            console.log("async1 start");
            //在async函数中，遇到await 会继续执行其他代码 再将await后面的代码放入微任务队列中
            await async2();
            console.log("async1 end"); //放入到微任务当中
        }
        async function async2() {
            console.log("async2");
        }
        console.log("script start");
        setTimeout(() => {
            console.log("setTimeout");
        }, 0);
        async1();
        new Promise(function (resolve) {
            console.log("promise1");
            resolve();//这行代码其实执行的是.then里面的代码 但是.then是微任务所以进入微任务队列
        }).then(function () {
            console.log("promise2");//微任务 等待
        });
  /*
        同步：('script start') ('async1 start')  ('async2') ('promise1')
        异步：
          微：('async1 end') ('promise2')
          宏：('setTimeout')
        */
    </script>
</body>

</html>